﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace YMSoft.SqLite
{
    public abstract class CfTypeRepository<T> : CfRepository where T : class,new()
    {
        public T GetCfExtension()
        {
            var result = new T();

            Do(result, (obj, cf, p) =>
                {
                    if (cf == null)
                    {
                        return;
                    }

                    if (p.PropertyType.Equals(typeof(string)))
                    {
                        p.SetValue(obj, cf.Value, null);
                    }
                    else
                    {
                        var convert = System.ComponentModel.TypeDescriptor.GetConverter(p.PropertyType);
                        var value = convert.ConvertFromString(cf.Value);
                        p.SetValue(obj, value, null);
                    }
                });

            return result;
        }

        public void SaveCfExtension(T target)
        {
            Do(target, (obj, cf, p) =>
            {
                if (cf == null)
                {
                    cf = new SyConfig();
                    cf.TypeName = typeof(T).Name;
                    cf.Code = p.Name;
                }
                var value = p.GetValue(obj, null);
                if (value == null)
                {
                    cf.Value = "";
                }
                else
                {
                    cf.Value = value.ToString();
                }
                Save(cf);
            });

        }

        void Do(T obj, Action<T, SyConfig, PropertyInfo> action)
        {
            var typeName = typeof(T).Name;
            var list = GetTable().Where(p => p.TypeName == typeName).ToList();
            var ps = typeof(T).GetProperties();
            var ins = from p in ps
                      join item in list on p.Name equals item.Code into ls
                      from l in ls.DefaultIfEmpty()
                      select new { Cf = l, P = p };
            ins.ToList().ForEach(p =>
            {
                action(obj, p.Cf, p.P);
            });
        }
    }
}
